package main

import (
	"context"
	"encoding/base64"
	"errors"
	"fmt"
	"github.com/chromedp/cdproto/cdp"
	"github.com/chromedp/chromedp"
	"log"
	"math/rand"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"time"
)

// 有问题的id: 13078
func main() {
	imgPattern := regexp.MustCompile(`data:image/([a-z]+);base64,(.*)`)

	novels := []string{"14478", "14578", "14606", "14615", "13078", "13392", "13038"}
	novelURLBase := "https://yyk06.xyz/ui/comics/info?k=base&id=%s"
	var err error

	ctx, cancel := chromedp.NewContext(context.Background())
	defer cancel()

	for _, novelId := range novels {
		novelURL := fmt.Sprintf(novelURLBase, novelId)
		var chapters []*cdp.Node
		var novelName string

		err = chromedp.Run(
			ctx,
			chromedp.Navigate(novelURL),
			chromedp.WaitVisible(".chapter-list", chromedp.ByQuery),
			chromedp.Nodes(".chapter-list>.chapter-item", &chapters, chromedp.ByQueryAll),
			chromedp.Text("span.info-title", &novelName, chromedp.ByQuery),
		)
		if err != nil {
			log.Fatal(err)
		}

		for _, node := range chapters {
			time.Sleep(time.Second * time.Duration(rand.Int63n(5-2)+2))

			chapterIndex, ok := node.Attribute("data-index")
			if !ok {
				log.Fatal("can not find chapter index:", novelId, chapters)
			}

			fmt.Println(fmt.Sprintf("start downloading: %s(%s)-%s", novelName, novelId, chapterIndex))

			chapterIndexInt, _ := strconv.Atoi(chapterIndex)
			imageURLs, err := getChapterImageURL(novelId, chapterIndexInt)
			if err != nil {
				log.Fatal("getChapterImageURL error:", err)
			}
			for i, imgURL := range imageURLs {
				content, err := getImageContent(imgURL)
				if err != nil {
					if errors.Is(err, Err404) {
						continue
					}
					log.Fatal("getImageContent error:", err)
				}
				imgInfo := imgPattern.FindStringSubmatch(content)
				if len(imgInfo) < 1 {
					log.Fatal("can not find image content:", content)
				}

				saveName := fmt.Sprintf("%d.%s", i+1, imgInfo[1])
				savePath := filepath.Join("novels", fmt.Sprintf("%s-%s", novelName, novelId), chapterIndex)
				err = os.MkdirAll(savePath, os.ModePerm)
				if err != nil {
					log.Fatalln("create dir error:", err)
				}
				decodeImg, err := base64.StdEncoding.DecodeString(imgInfo[2])
				if err != nil {
					log.Fatalln("decode img error:", err)
				}
				err = os.WriteFile(filepath.Join(savePath, saveName), decodeImg, os.ModePerm)
				if err != nil {
					log.Fatalln("write file error:", err)
				}
			}

			//var imgs []*cdp.Node
			//if err = chromedp.Run(
			//	ctx, chromedp.Navigate(chapterURL),
			//	chromedp.WaitVisible(".chapter-body>img"),
			//	chromedp.Nodes(".chapter-body>img", &imgs, chromedp.ByQueryAll),
			//); err != nil {
			//	log.Fatalln("open chapter url error:", err)
			//}
			//for i, img := range imgs {
			//	src, _ := img.Attribute("src")
			//	imgInfo := imgPattern.FindStringSubmatch(src)
			//	if len(imgInfo) < 1 {
			//		log.Println("can not find src:", chapterIndex, chapterURL, src)
			//		continue
			//	}
			//
			//	saveName := fmt.Sprintf("%s_%d.%s", chapterIndex, i+1, imgInfo[1])
			//	savePath := filepath.Join("novels", fmt.Sprintf("%s-%d", novelName, novelId))
			//	err = os.MkdirAll(savePath, os.ModePerm)
			//	if err != nil {
			//		log.Fatalln("create dir error:", err)
			//	}
			//	decodeImg, err := base64.StdEncoding.DecodeString(imgInfo[2])
			//	if err != nil {
			//		log.Fatalln("decode img error:", err)
			//	}
			//	err = os.WriteFile(filepath.Join(savePath, saveName), decodeImg, os.ModePerm)
			//	if err != nil {
			//		log.Fatalln("write file error:", err)
			//	}
			//}
		}
	}

	fmt.Println("all task done")
}
